﻿using System;
using System.Xml;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime;
using System.Runtime.InteropServices;

namespace PickGold.Util.Proxies
{
	/// <summary>
	/// 属性读取器接口。
	/// </summary>
	public interface IPropertiesAccessor
	{
		/// <summary>
		/// 获取或设置属性值或方法委托。
		/// </summary>
		/// <param name="key">属性或方法键名。</param>
		/// <returns>属性值或方法委托。</returns>
		object this[object key] { get; set; }
		/// <summary>
		/// 指示是否存在指定的属性或方法键名。
		/// </summary>
		/// <param name="key">属性或方法键名。</param>
		/// <returns>是否存在指定的属性或方法键名。</returns>
		bool Contains(object key);
		/// <summary>
		/// 对象是否是只读的，如果是只读的，所有设置操作将全部失效。
		/// </summary>
		bool IsReadOnly { get; }
		/// <summary>
		/// 实际对象。
		/// </summary>
		object Real { get; }
	}

	/// <summary>
	/// 直接对象属性访问器。
	/// </summary>
	[Serializable]
	[ComVisible(true)]
	[ClassInterface(ClassInterfaceType.AutoDispatch)]
	public class ObjectPropertiesAccessor : IPropertiesAccessor
	{
		private object _Real;

		/// <summary>
		/// 构造一对象属性访问器。
		/// </summary>
		/// <param name="real">访问对象。</param>
		public ObjectPropertiesAccessor(object real)
		{
			this._Real = real;
		}

		#region IPropertiesAccessor 成员

		object IPropertiesAccessor.this[object key]
		{
			get
			{
				throw new NotSupportedException();
			}
			set
			{
				throw new NotSupportedException();
			}
		}

		bool IPropertiesAccessor.Contains(object key)
		{
			return false;
		}

		bool IPropertiesAccessor.IsReadOnly
		{
			get
			{
				return true;
			}
		}

		object IPropertiesAccessor.Real
		{
			get
			{
				return this._Real;
			}
		}

		#endregion
	}

	public class XmlDictionary : MarshalByRefObject, IDictionary
	{
		private XmlDocument _Xml;

		public XmlDictionary(XmlDocument xml)
		{
			this._Xml = xml;
			if(this._Xml == null)
				this._Xml = new XmlDocument();
			if (this._Xml.DocumentElement == null)
				this._Xml.AppendChild(this._Xml.CreateElement(typeof(XmlDictionary).Name));
		}

		#region IDictionary 成员

		public void Add(object key, object value)
		{
			var v = value as string;
			if (v == null)
				v = value + string.Empty;
			if (key == null || key.Equals(string.Empty))
			{
				this._Xml.DocumentElement.InnerText = v;
				return;
			}

			var k = key as string;
			if (!string.IsNullOrEmpty(k))
			{
				var xa = this._Xml.DocumentElement.Attributes[k];
				xa.Value = v;
			}

			k = key + string.Empty;
			for (var i = 0; i < this._Xml.DocumentElement.ChildNodes.Count; i++)
			{
				var xn = this._Xml.DocumentElement.ChildNodes[i];
				var xa = xn.Attributes["id"];
				if (xa == null)
					continue;

				if (string.Compare(xa.Value, k, StringComparison.OrdinalIgnoreCase) == 0)
				{
					return;
				}
			}
		}

		public void Clear()
		{
			throw new NotImplementedException();
		}

		public bool Contains(object key)
		{
			throw new NotImplementedException();
		}

		public IDictionaryEnumerator GetEnumerator()
		{
			throw new NotImplementedException();
		}

		public bool IsFixedSize
		{
			get { throw new NotImplementedException(); }
		}

		public bool IsReadOnly
		{
			get { throw new NotImplementedException(); }
		}

		public ICollection Keys
		{
			get { throw new NotImplementedException(); }
		}

		public void Remove(object key)
		{
			throw new NotImplementedException();
		}

		public ICollection Values
		{
			get { throw new NotImplementedException(); }
		}

		public object this[object key]
		{
			get
			{
				throw new NotImplementedException();
			}
			set
			{
				throw new NotImplementedException();
			}
		}

		#endregion

		#region ICollection 成员

		public void CopyTo(Array array, int index)
		{
			throw new NotImplementedException();
		}

		public int Count
		{
			get { throw new NotImplementedException(); }
		}

		public bool IsSynchronized
		{
			get { throw new NotImplementedException(); }
		}

		public object SyncRoot
		{
			get { throw new NotImplementedException(); }
		}

		#endregion

		#region IEnumerable 成员

		IEnumerator IEnumerable.GetEnumerator()
		{
			throw new NotImplementedException();
		}

		#endregion
	}
}
